package com.carbeauty.entity;

import com.carbeauty.common.entity.BaseEntity;
import com.carbeauty.common.enums.OrderStatus;
import com.carbeauty.common.enums.PaymentMethod;
import com.fasterxml.jackson.annotation.JsonFormat;
import jakarta.persistence.*;
import jakarta.validation.constraints.DecimalMin;
import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Size;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;

/**
 * 服务订单实体类
 * 
 * 订单管理功能:
 * - 订单基本信息
 * - 客户信息关联
 * - 服务项目关联
 * - 支付信息管理
 * - 订单状态跟踪
 * 
 * @author CarBeauty Team
 */
@Entity
@Table(name = "cb_service_order")
public class ServiceOrder extends BaseEntity {
    
    /**
     * 订单号 - 唯一标识
     */
    @Column(name = "order_no", nullable = false, unique = true, length = 32)
    private String orderNo;
    
    /**
     * 客户ID - 不使用外键约束
     */
    @NotNull(message = "客户ID不能为空")
    @Column(name = "customer_id", nullable = false)
    private Long customerId;
    
    /**
     * 客户姓名 - 冗余字段，便于查询
     */
    @Size(max = 50, message = "客户姓名长度不能超过50个字符")
    @Column(name = "customer_name", length = 50)
    private String customerName;
    
    /**
     * 客户手机号 - 冗余字段，便于查询
     */
    @Size(max = 11, message = "手机号长度不能超过11个字符")
    @Column(name = "customer_phone", length = 11)
    private String customerPhone;
    
    /**
     * 车牌号
     */
    @Size(max = 20, message = "车牌号长度不能超过20个字符")
    @Column(name = "car_number", length = 20)
    private String carNumber;
    
    /**
     * 服务员工ID - 不使用外键约束
     */
    @Column(name = "employee_id")
    private Long employeeId;
    
    /**
     * 服务员工姓名 - 冗余字段
     */
    @Size(max = 50, message = "员工姓名长度不能超过50个字符")
    @Column(name = "employee_name", length = 50)
    private String employeeName;
    
    /**
     * 订单日期
     */
    @NotNull(message = "订单日期不能为空")
    @Column(name = "order_date", nullable = false)
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private LocalDateTime orderDate;
    
    /**
     * 预约服务时间
     */
    @Column(name = "appointment_time")
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private LocalDateTime appointmentTime;
    
    /**
     * 实际服务开始时间
     */
    @Column(name = "service_start_time")
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private LocalDateTime serviceStartTime;
    
    /**
     * 实际服务结束时间
     */
    @Column(name = "service_end_time")
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private LocalDateTime serviceEndTime;
    
    /**
     * 订单状态
     */
    @Enumerated(EnumType.STRING)
    @Column(name = "order_status", nullable = false, length = 20)
    private OrderStatus orderStatus = OrderStatus.PENDING;
    
    /**
     * 服务项目总金额
     */
    @NotNull(message = "服务金额不能为空")
    @DecimalMin(value = "0", message = "服务金额不能为负数")
    @Column(name = "service_amount", nullable = false, precision = 10, scale = 2)
    private BigDecimal serviceAmount = BigDecimal.ZERO;
    
    /**
     * 材料费用
     */
    @DecimalMin(value = "0", message = "材料费用不能为负数")
    @Column(name = "material_amount", precision = 10, scale = 2)
    private BigDecimal materialAmount = BigDecimal.ZERO;
    
    /**
     * 折扣金额
     */
    @DecimalMin(value = "0", message = "折扣金额不能为负数")
    @Column(name = "discount_amount", precision = 10, scale = 2)
    private BigDecimal discountAmount = BigDecimal.ZERO;
    
    /**
     * 实际支付金额
     */
    @NotNull(message = "支付金额不能为空")
    @DecimalMin(value = "0", message = "支付金额不能为负数")
    @Column(name = "paid_amount", nullable = false, precision = 10, scale = 2)
    private BigDecimal paidAmount = BigDecimal.ZERO;
    
    /**
     * 支付方式
     */
    @Enumerated(EnumType.STRING)
    @Column(name = "payment_method", length = 20)
    private PaymentMethod paymentMethod;
    
    /**
     * 支付时间
     */
    @Column(name = "payment_time")
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private LocalDateTime paymentTime;
    
    /**
     * 使用积分
     */
    @Column(name = "used_points")
    private Integer usedPoints = 0;
    
    /**
     * 获得积分
     */
    @Column(name = "earned_points")
    private Integer earnedPoints = 0;
    
    /**
     * 订单备注
     */
    @Size(max = 500, message = "订单备注长度不能超过500个字符")
    @Column(name = "order_remark", length = 500)
    private String orderRemark;
    
    /**
     * 服务评价(1-5星)
     */
    @Column(name = "rating")
    private Integer rating;
    
    /**
     * 评价内容
     */
    @Size(max = 500, message = "评价内容长度不能超过500个字符")
    @Column(name = "review", length = 500)
    private String review;
    
    /**
     * 评价时间
     */
    @Column(name = "review_time")
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private LocalDateTime reviewTime;
    
    // ==================== 构造方法 ====================
    
    public ServiceOrder() {
        super();
        this.orderDate = LocalDateTime.now();
        this.generateOrderNo();
    }
    
    public ServiceOrder(Long customerId, String customerName, String customerPhone) {
        this();
        this.customerId = customerId;
        this.customerName = customerName;
        this.customerPhone = customerPhone;
    }
    
    // ==================== Getter/Setter ====================
    
    public String getOrderNo() {
        return orderNo;
    }
    
    public void setOrderNo(String orderNo) {
        this.orderNo = orderNo;
    }
    
    public Long getCustomerId() {
        return customerId;
    }
    
    public void setCustomerId(Long customerId) {
        this.customerId = customerId;
    }
    
    public String getCustomerName() {
        return customerName;
    }
    
    public void setCustomerName(String customerName) {
        this.customerName = customerName;
    }
    
    public String getCustomerPhone() {
        return customerPhone;
    }
    
    public void setCustomerPhone(String customerPhone) {
        this.customerPhone = customerPhone;
    }
    
    public String getCarNumber() {
        return carNumber;
    }
    
    public void setCarNumber(String carNumber) {
        this.carNumber = carNumber;
    }
    
    public Long getEmployeeId() {
        return employeeId;
    }
    
    public void setEmployeeId(Long employeeId) {
        this.employeeId = employeeId;
    }
    
    public String getEmployeeName() {
        return employeeName;
    }
    
    public void setEmployeeName(String employeeName) {
        this.employeeName = employeeName;
    }
    
    public LocalDateTime getOrderDate() {
        return orderDate;
    }
    
    public void setOrderDate(LocalDateTime orderDate) {
        this.orderDate = orderDate;
    }
    
    public LocalDateTime getAppointmentTime() {
        return appointmentTime;
    }
    
    public void setAppointmentTime(LocalDateTime appointmentTime) {
        this.appointmentTime = appointmentTime;
    }
    
    public LocalDateTime getServiceStartTime() {
        return serviceStartTime;
    }
    
    public void setServiceStartTime(LocalDateTime serviceStartTime) {
        this.serviceStartTime = serviceStartTime;
    }
    
    public LocalDateTime getServiceEndTime() {
        return serviceEndTime;
    }
    
    public void setServiceEndTime(LocalDateTime serviceEndTime) {
        this.serviceEndTime = serviceEndTime;
    }
    
    public OrderStatus getOrderStatus() {
        return orderStatus;
    }

    public void setOrderStatus(OrderStatus orderStatus) {
        this.orderStatus = orderStatus;
    }
    
    public BigDecimal getServiceAmount() {
        return serviceAmount;
    }
    
    public void setServiceAmount(BigDecimal serviceAmount) {
        this.serviceAmount = serviceAmount;
    }
    
    public BigDecimal getMaterialAmount() {
        return materialAmount;
    }
    
    public void setMaterialAmount(BigDecimal materialAmount) {
        this.materialAmount = materialAmount;
    }
    
    public BigDecimal getDiscountAmount() {
        return discountAmount;
    }
    
    public void setDiscountAmount(BigDecimal discountAmount) {
        this.discountAmount = discountAmount;
    }
    
    public BigDecimal getPaidAmount() {
        return paidAmount;
    }
    
    public void setPaidAmount(BigDecimal paidAmount) {
        this.paidAmount = paidAmount;
    }
    
    public PaymentMethod getPaymentMethod() {
        return paymentMethod;
    }
    
    public void setPaymentMethod(PaymentMethod paymentMethod) {
        this.paymentMethod = paymentMethod;
    }
    
    public LocalDateTime getPaymentTime() {
        return paymentTime;
    }
    
    public void setPaymentTime(LocalDateTime paymentTime) {
        this.paymentTime = paymentTime;
    }
    
    public Integer getUsedPoints() {
        return usedPoints;
    }
    
    public void setUsedPoints(Integer usedPoints) {
        this.usedPoints = usedPoints;
    }
    
    public Integer getEarnedPoints() {
        return earnedPoints;
    }
    
    public void setEarnedPoints(Integer earnedPoints) {
        this.earnedPoints = earnedPoints;
    }
    
    public String getOrderRemark() {
        return orderRemark;
    }
    
    public void setOrderRemark(String orderRemark) {
        this.orderRemark = orderRemark;
    }
    
    public Integer getRating() {
        return rating;
    }
    
    public void setRating(Integer rating) {
        this.rating = rating;
    }
    
    public String getReview() {
        return review;
    }
    
    public void setReview(String review) {
        this.review = review;
    }
    
    public LocalDateTime getReviewTime() {
        return reviewTime;
    }
    
    public void setReviewTime(LocalDateTime reviewTime) {
        this.reviewTime = reviewTime;
    }
    
    // ==================== 业务方法 ====================
    
    /**
     * 生成订单号
     */
    public void generateOrderNo() {
        if (this.orderNo == null || this.orderNo.isEmpty()) {
            // 格式: CB + 年月日时分秒 + 4位随机数
            String timestamp = java.time.LocalDateTime.now()
                .format(java.time.format.DateTimeFormatter.ofPattern("yyyyMMddHHmmss"));
            String random = String.format("%04d", (int)(Math.random() * 10000));
            this.orderNo = "CB" + timestamp + random;
        }
    }
    
    /**
     * 计算订单总金额
     */
    public BigDecimal getTotalAmount() {
        return serviceAmount.add(materialAmount);
    }
    
    /**
     * 计算应付金额
     */
    public BigDecimal getPayableAmount() {
        return getTotalAmount().subtract(discountAmount);
    }
    
    /**
     * 确认订单
     */
    public void confirm() {
        this.orderStatus = OrderStatus.CONFIRMED;
    }

    /**
     * 开始服务
     */
    public void startService() {
        this.orderStatus = OrderStatus.IN_PROGRESS;
        this.serviceStartTime = LocalDateTime.now();
    }

    /**
     * 完成服务
     */
    public void completeService() {
        this.orderStatus = OrderStatus.COMPLETED;
        this.serviceEndTime = LocalDateTime.now();
    }

    /**
     * 取消订单
     */
    public void cancel() {
        this.orderStatus = OrderStatus.CANCELLED;
    }
    
    /**
     * 支付订单
     */
    public void pay(PaymentMethod method, BigDecimal amount) {
        this.paymentMethod = method;
        this.paidAmount = amount;
        this.paymentTime = LocalDateTime.now();
    }
    
    /**
     * 添加评价
     */
    public void addReview(Integer rating, String review) {
        this.rating = rating;
        this.review = review;
        this.reviewTime = LocalDateTime.now();
    }
    
    /**
     * 检查是否已支付
     */
    public boolean isPaid() {
        return paymentTime != null && paidAmount.compareTo(BigDecimal.ZERO) > 0;
    }
    
    /**
     * 检查是否已完成
     */
    public boolean isCompleted() {
        return OrderStatus.COMPLETED.equals(this.orderStatus);
    }

    /**
     * 检查是否已取消
     */
    public boolean isCancelled() {
        return OrderStatus.CANCELLED.equals(this.orderStatus);
    }
    
    /**
     * 计算服务时长(分钟)
     */
    public Long getServiceDuration() {
        if (serviceStartTime != null && serviceEndTime != null) {
            return java.time.Duration.between(serviceStartTime, serviceEndTime).toMinutes();
        }
        return null;
    }
}
